<!--
 * @Author: ChunLai
 * @Date: 2022-01-07 08:51:46
 * @LastEditTime: 2025-09-08 14:13:38
 * @Description: 证件Ocr识别Pop弹出框
 * @FilePath: \02.bldinsure\src\components\OcrRecoganizePop.vue
-->
<template>
  <van-popup
    v-model="showDialog"
    lock-scroll
    position="bottom"
    closeable
    round
    sticky
    get-container="body"
    @click-close-icon="closePop"
    @click-overlay="closePop"
  >
    <div class="pop-main-cont">
      <div class="popup-mode-head">OCR识别认证</div>
      <div class="warn-tip" v-if="showWarnTip">
        <div class="tip-txt">
          拍摄时请确保{{
            ocrType == "bank" ? "银行卡" : "身份证"
          }}边框完整、字迹清晰、亮度均衡， 必须为原件拍摄，否则后期质检不过
        </div>
        <MsImgIcon
          size="14"
          name="cross2"
          @click.native="showWarnTip = false"
        />
      </div>
      <div class="pop-conts">
        <div class="ocr-flex">
          <div class="upload-area" @click="imgtype = 'face'">
            <van-uploader
              :max-count="1"
              :after-read="afterRead"
              v-if="zUrl !== ''"
            >
              <div class="reupload">
                <van-image class="imgBox" fit="cover" :src="zUrl" />
                <div class="show-div">点击重拍</div>
              </div>
            </van-uploader>
            <van-uploader :max-count="1" :after-read="afterRead" v-else>
              <div class="card-box">
                <img
                  :src="`${imgUrlPath}/img/${
                    ocrType === 'bank' ? 'eg_common.png' : 'ocr_z.jpg'
                  }`"
                  alt=""
                />
              </div>
              <p class="p-txt">
                点击拍摄/{{ ocrType === "bank" ? "上传账号面" : "上传人像面" }}
              </p>
            </van-uploader>
          </div>
          <div class="upload-infos" v-if="ocrMsg.idNum || ocrMsg.bankAccNo">
            <div class="msg-list" v-if="ocrType === 'bank'">
              <p>开户银行：{{ ocrMsg.bankCodename }}</p>
              <p>银行卡号：{{ ocrMsg.bankAccNo }}</p>
            </div>
            <div class="msg-list" v-else>
              <p>姓名：{{ ocrMsg.name }}</p>
              <p>身份证号： {{ ocrMsg.idNum }}</p>
              <p>性别：{{ ocrMsg.sexName }}</p>
              <p>出生日期：{{ ocrMsg.birthDate }}</p>
            </div>
          </div>
        </div>
        <!-- 证件反面 -->
        <div class="ocr-flex" v-if="ocrType !== 'bank'">
          <div class="upload-area" @click="imgtype = 'back'">
            <van-uploader
              :max-count="1"
              :after-read="afterRead"
              v-if="fUrl !== ''"
            >
              <div class="reupload">
                <van-image class="imgBox" fit="cover" :src="fUrl" />
                <div class="show-div">点击重拍</div>
              </div>
            </van-uploader>
            <van-uploader :max-count="1" :after-read="afterRead" v-else>
              <div class="card-box">
                <img :src="`${imgUrlPath}/img/ocr_f.jpg`" alt="" />
              </div>
              <p class="p-txt">点击拍摄/上传国徽面</p>
            </van-uploader>
          </div>
          <div class="upload-infos" v-if="ocrMsg.validDate">
            <div class="msg-list">
              <p>有效期起期：{{ ocrMsg.validDate }}</p>
              <p>
                有效期止期：{{
                  ocrMsg.validDateEnd == this.longTime
                    ? "长期"
                    : ocrMsg.validDateEnd
                }}
              </p>
            </div>
          </div>
        </div>
      </div>
      <div class="pop-foot-box" @click="sureOcrRes">提交</div>
    </div>
  </van-popup>
</template>

<script>
import { mapGetters } from "vuex";
import { bankCardAttribution } from "@/utils/GetBankName";
import { dayDiffValue, IdentityCodeValid } from "@/methods/userinfos.js";

export default {
  name: "OcrRecoganizePop",
  props: {
    showOcrPop: {
      type: Boolean,
      default: false,
    },
    onlyface: {
      type: Boolean,
      default: false,
    },
    ocrType: {
      type: String,
      default: "tbr", // bank
    },
    bankType: {
      type: String,
      default: "R", // bank
    },
  },
  data() {
    return {
      zUrl: "",
      fUrl: "",
      imgtype: "",
      ocrMsg: {
        birthDate: "",
        idNum: "",
        name: "",
        sex: "",
        sexName: "",
        validDate: "",
        validDateEnd: "",
        bankAccNo: "",
        bankCodename: "",
        bankCode: "",
      },
      bankmsg: {},
      showWarnTip: true,
      loadingTips: "",
    };
  },
  computed: {
    showDialog: {
      get: function () {
        return this.showOcrPop;
      },
      set: function (value) {},
    },
    ...mapGetters({
      bankList: "dictionary/bankList",
      longTime: "dictionary/longTime",
    }),
  },
  created() {},
  methods: {
    afterRead(file) {
      if (file.file.size > 204800) {
        let canvas = document.createElement("canvas");
        let context = canvas.getContext("2d");
        let img = new Image();
        img.src = file.content;
        img.onload = () => {
          const whRatio = img.width / img.height;
          const nw = 750;
          const nh = Math.ceil(nw / whRatio);
          canvas.width = nw;
          canvas.height = nh;
          context.drawImage(img, 0, 0, nw, nh);
          file.content = canvas.toDataURL(file.file.type, 0.92);
          this.getFileUpload(file.content);
        };
      } else {
        this.getFileUpload(file.content);
      }
    },
    // 公共接口
    getFileUpload(imgBase) {
      this.$store.commit("updateLoadTxt", "文件上传中，请稍后");
      let pic_base64 = imgBase
        .replace(new RegExp("image/jpeg", ""), "image/jpg")
        .replace(new RegExp("image/png", ""), "image/jpg");
      this.$store.dispatch("apis/fileAdminUpload", pic_base64).then((data) => {
        if (this.ocrType === "bank") {
          this.checkBankNum(data.url);
        } else {
          this.checkIdNum(data.url, this.imgtype);
        }
      });
    },
    checkIdNum(imgUrl, imgtype) {
      this.$store.commit("updateLoad", true);
      this.$store.commit("updateLoadTxt", "正在识别文件，请稍后");
      this.$http
        .post("/aliyun/oss/ocrIdCardRecoganize", {
          url: imgUrl,
          side: imgtype, // face是脸，back是背面
        })
        .then(({ data }) => {
          this.$store.commit("updateLoad", false);
          const resMsg = data.data,
            faceMsg = resMsg.frontResult,
            backMsg = resMsg.backResult;
          // 证件用户类型
          faceMsg.userType = "22"; //受益人
          if (this.ocrType === "bbr") {
            faceMsg.userType = "21"; //被保人
          } else if (this.ocrType === "tbr") {
            faceMsg.userType = "20"; //投保人
          }
          this.$nextTick(() => {
            if (imgtype === "face") {
              // 证件类型
              faceMsg.imgType = "5";
              if (faceMsg.name) {
                this.ocrMsg.name = faceMsg.name;
              }
              if (faceMsg.iDNumber) {
                let idFlag = IdentityCodeValid(faceMsg.iDNumber);
                if (idFlag) {
                  this.ocrMsg.idNum = faceMsg.iDNumber;
                  // 出生日期和性别 用身份证计算的结果 减少失败误差
                  this.ocrMsg.birthDate =
                    faceMsg.iDNumber.substring(6, 10) +
                    "-" +
                    faceMsg.iDNumber.substring(10, 12) +
                    "-" +
                    faceMsg.iDNumber.substring(12, 14);
                  let xbnum = faceMsg.iDNumber.substring(16, 17);
                  this.ocrMsg.sex = xbnum % 2 === 0 ? "1" : "0";
                  this.ocrMsg.sexName = xbnum % 2 === 0 ? "女" : "男";
                  this.saveImgInfo(imgUrl, faceMsg);
                } else {
                  this.$toast("身份证识别有误，您可以提交后手动输入");
                }
              }
              this.zUrl = imgUrl;
            } else if (imgtype === "back") {
              faceMsg.imgType = "6";
              if (backMsg.startDate) {
                this.ocrMsg.validDate = this.formatDate(backMsg.startDate);
              }
              if (backMsg.endDate) {
                this.ocrMsg.validDateEnd =
                  backMsg.endDate === "长期"
                    ? this.longTime
                    : this.formatDate(backMsg.endDate);
              }
              if (!backMsg.endDate || !backMsg.startDate) {
                this.$toast("身份证有效期识别有误，您可以提交后手动修改");
              }
              faceMsg.iDNumber = this.ocrMsg.idNum || "";
              this.saveImgInfo(imgUrl, faceMsg);
              this.fUrl = imgUrl;
            }
          });
        })
        .catch((err) => {
          this.$store.commit("updateLoad", false);
        });
    },
    formatDate(val) {
      return `${val.substring(0, 4)}-${val.substring(4, 6)}-${val.substring(
        6,
        8
      )}`;
    },
    checkBankNum(imgUrl) {
      this.$store.commit("updateLoad", true);
      this.$store.commit("updateLoadTxt", "正在识别文件，请稍后");
      this.$http
        .post("/aliyun/oss/ocrBankCardRecoganize", {
          url: imgUrl,
        })
        .then(({ data }) => {
          this.$store.commit("updateLoad", false);
          let resMsg = data.data;
          this.ocrMsg.bankAccNo = resMsg.cardNumber;
          this.ocrMsg.bankCodename = resMsg.bankName;
          this.zUrl = imgUrl;
          resMsg.userType = "31";
          resMsg.imgType = "7";
          this.saveImgInfo(imgUrl, resMsg);
        })
        .catch((err) => {
          this.$store.commit("updateLoad", false);
        });
    },
    sureOcrRes() {
      if (this.ocrType === "bank") {
        if (this.ocrMsg.bankAccNo === "") {
          return this.$toast("请拍摄开户银行卡");
        }
        return this.getBankCode(
          this.ocrMsg.bankCodename,
          this.ocrMsg.bankAccNo
        );
      } else {
        if (!this.zUrl) {
          return this.$toast("请拍摄证件照正面");
        }
        if (!this.onlyface && !this.fUrl) {
          return this.$toast("请拍摄证件照反面");
        }
        if (
          this.ocrMsg.validDateEnd &&
          this.ocrMsg.validDateEnd !== this.longTime
        ) {
          let gapDay = dayDiffValue(
            new Date(),
            new Date(
              this.formatDate(this.ocrMsg.validDateEnd).replace(/-/g, "/")
            )
          );
          if (gapDay < 1) {
            return this.$toast("身份证已过期，请及时换证");
          } else if (gapDay < 30) {
            this.$toast("身份证已临期，请及时换证");
          }
        }
      }
      this.ocrMsg.zPicUrl = this.zUrl || "";
      this.ocrMsg.fPicUrl = this.fUrl || "";
      this.$emit("sureBtn", this.ocrMsg);
    },
    getBankCode(bankName, bankNo) {
      let isbank = false,
        value = bankName;
      // 通过银行卡号获取银行卡名称（对应字典名称）
      let info = bankCardAttribution(bankNo);
      if (info && info.bankName) {
        value = info.bankName;
      }
      let target = this.bankList.find((item) => {
        if (
          item.text == value ||
          value.indexOf(item.text) !== -1 ||
          item.text.indexOf(value) !== -1
        ) {
          this.ocrMsg.bankCode = item.keyId;
          return true;
        }
        return false;
      });
      if (!target) {
        this.$toast("当前产品投保不支持该银行卡,请更换银行卡或手动输入");
        this.ocrMsg.bankCode = "";
        this.ocrMsg.bankCodename = "";
      } else {
        if (!target.bank7 && target.bankR) {
          // 仅支持实时扣款
          this.ocrMsg.payMode = "R";
        }
        if (!target.bankR && target.bank7) {
          // 仅支持批次
          this.ocrMsg.payMode = "7";
        }
      }
      this.ocrMsg.zPicUrl = this.zUrl || "";
      this.$emit("sureBtn", this.ocrMsg);
    },
    closePop() {
      this.$emit("sureBtn", null);
    },
    saveImgInfo(picUrl, datas) {
      let params = {
        ...this.apiComParams,
        type: datas.userType,
        imgType: datas.imgType,
        imgUrl: picUrl,
        idNum: datas.iDNumber || "",
        ocrFlag: "Y",
      };
      this.$store.dispatch("apis/comAdminApiRequest", {
        apiParams: params,
        apiName: "saveImg",
      });
    },
  },
};
</script>

<style lang="less" scoped>
.warn-tip {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 50px;
  padding: 6px 12px 0;
  color: #f8ad00;
  background: #fdfcec;

  .tip-txt {
    display: flex;
    width: 86%;
    font-size: 12px;
    line-height: 16px;
  }
}
.pop-conts {
  min-height: 280px;
  padding: 10px 12px;
}
.ocr-flex {
  display: flex;
  width: 100%;
  height: 130px;
  margin-bottom: 20px;
  .upload-area {
    width: 150px;
    margin-right: 10px;
    .card-box {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 150px;
      height: 100px;
      background: #f4f8fe;
      border-radius: 10px 10px 0px 0px;
      padding: 0 20px;
    }
    .p-txt {
      width: 150px;
      height: 30px;
      line-height: 30px;
      background: #6699ff;
      border-radius: 0px 0px 10px 10px;
      text-align: center;
      font-size: 12px;
      color: #fff;
    }
    .reupload {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 150px;
      height: 130px;
      padding: 0 5px;
      position: relative;
      border-radius: 10px;
      overflow: hidden;

      .imgBox {
        width: 100%;
      }

      .show-div {
        position: absolute;
        top: 0;
        left: 0;
        display: flex;
        justify-content: center;
        align-items: flex-end;
        width: 100%;
        height: 100%;
        line-height: 20px;
        color: #ffffff;
        letter-spacing: 2px;
        background-color: rgba(0, 0, 0, 0.36);
      }
    }
  }
  .upload-infos {
    padding-top: 10px;
  }
}

.pop-foot-box {
  width: 100%;
  height: 50px;
  line-height: 50px;
  text-align: center;
  font-size: 18px;
  font-family: MiSans;
  color: #ffffff;
  letter-spacing: 2px;
  box-shadow: rgba(0, 0, 0, 0.3) 0px 2px 12px 0px;
  background: linear-gradient(270deg, #cb1800 0%, #ff462c 100%);
}

/deep/.van-popup__close-icon {
  top: 10px;
}
</style>
